package org.mbds.sensorsdatacollector.android;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.mbds.sensorsdatacollector.android.config.Properties;
import org.mbds.sensorsdatacollector.android.db.SensorsDataSQLiteDatabase;
import org.mbds.sensorsdatacollector.android.tools.FileUtilities;
import org.mbds.sensorsdatacollector.android.tools.GPSTools;
import org.mbds.sensorsdatacollector.android.tools.SensorsDataManager;
import org.mbds.sensorsdatacollector.android.tools.StaticCommons;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.os.Environment;
import android.os.StrictMode;


public class SensorsDataCollectorApplication extends Application  
{ 
	public static final String TAG = "SensorsDataCollectorApplication";
	private static SensorsDataCollectorApplication instance = null;
	private static Context context = null;
	public static final String PREFS = "SensorsChartsPREFS";
	public SensorsDataManager sDM = null; // An instance of SensorsDataManager to manage starting and stopping sensors data collection

	public static SensorsDataCollectorApplication getInstance() {
		if (instance == null) {
			throw new IllegalStateException("Application not created yet!");
		}
		return instance;
	}
	
	// Moved to main activity
//	@Override
//	public void finalize() throws Throwable {
//		stopDataCollection();
//		super.finalize();
//	}
//	public static void stopDataCollection() {
//		//SensorsDataManager.magneticFieldData.stopDataCollection();
//		SensorsDataManager.accelerometerData.stopDataCollection();
//		/*SensorsDataManager.gyroscopeData.stopDataCollection();
//		SensorsDataManager.rotationData.stopDataCollection();
//		SensorsDataManager.linearAccelData.stopDataCollection();
//		SensorsDataManager.gravityData.stopDataCollection();
//		SensorsDataManager.pressureData.stopDataCollection();
//		SensorsDataManager.proximityData.stopDataCollection();*/
//	}
//	

	@Override
	public void onCreate() {
		super.onCreate();
		instance = this;
		context=getApplicationContext();
		// Retrieve previous setup
		SharedPreferences settings = getSharedPreferences(
				SensorsDataCollectorApplication.PREFS, Context.MODE_PRIVATE);

		if (android.os.Build.VERSION.SDK_INT > 9) { 
		      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
		      StrictMode.setThreadPolicy(policy); 
		}
	      /*********************************/
        /* Check if a SD card is present */
        /*********************************/
        if(isSdPresent())
        {
        	// A SD card is present then use it
        	/***********************************************************/
            /* Check if the geoloc directory is present on the SD card */
            /***********************************************************/
            if(checkDirectory(Properties.PATH, getApplicationContext())==false)
            {
            	// Copy the files from the resources
            	File geolocdir = new File(Properties.PATH);               
            	geolocdir.mkdirs();
                copyDefaultFiles(getApplicationContext());      
                
            }
        }
        // Init GPS
        GPSTools.initLocationManager(this);
		// Instanciation BDD
        SensorsDataSQLiteDatabase db = SensorsDataSQLiteDatabase.getInstance(this, "SensorsDataSQLiteDatabase");
        StaticCommons.setDatabaseManager(db);
	}
	
	// Moved to main activity
//	/*This method starts is called in order to register this class has a sensorObserverInterface implementer*/
//	public void startRegistring(){
//		//SensorsDataManager.magneticFieldData.addObserver(this);
//		SensorsDataManager.accelerometerData.addObserver(this);
//		/*SensorsDataManager.gyroscopeData.addObserver(this);
//		SensorsDataManager.rotationData.addObserver(this);
//		SensorsDataManager.linearAccelData.addObserver(this);
//		SensorsDataManager.gravityData.addObserver(this);
//		SensorsDataManager.pressureData.addObserver(this);
//		SensorsDataManager.proximityData.addObserver(this);*/
//	}
//	
//	/*This method does the exact contrary of the startRegistring, to unregister this class from the oberver list*/
//	public void stopRegistring() throws Throwable{
//		//SensorsDataManager.magneticFieldData.removeObserver(this);
//		SensorsDataManager.accelerometerData.removeObserver(this);
//		/*SensorsDataManager.gyroscopeData.removeObserver(this);
//		SensorsDataManager.rotationData.removeObserver(this);
//		SensorsDataManager.linearAccelData.removeObserver(this);
//		SensorsDataManager.gravityData.removeObserver(this);
//		SensorsDataManager.pressureData.removeObserver(this);
//		SensorsDataManager.proximityData.removeObserver(this);*/
//	}

	/*****************************/
	/* Copy files to the SD card */
	/*****************************/
	private static void copyDefaultFiles(Context ctx)
	{
		AssetManager assetManager = ctx.getResources().getAssets();
        String[] files = null;
        try
        {
        	files = assetManager.list(Properties.SD_DIRECTORY.replaceAll("/", ""));
        }
        catch (Exception e)
        {
        	FileUtilities.saveLog("read "+Properties.SD_DIRECTORY+" ERROR", e.toString(), 2);
            e.printStackTrace();
        }
        
        for(int i=0; i<files.length; i++)
        {
        	InputStream in = null;
            OutputStream out = null;
            try 
            {
            	in = assetManager.open(Properties.SD_DIRECTORY.replaceFirst("/", "") + files[i]);
            	out = new FileOutputStream(Properties.PATH + files[i]);
            	copyFile(in, out);
            	in.close();
            	in = null;
            	out.flush();
            	out.close();
            	out = null;
            }
            catch(Exception e) 
            {
            	FileUtilities.saveLog("copy "+Properties.SD_DIRECTORY+" ERROR",  e.toString(), 2);
                e.printStackTrace();
            }
        }

	}
	private static void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1)
        {
        	out.write(buffer, 0, read);
        }
    }

	/*****************************************************/
    /* Check if a directory exists or not on the SD card */
    /*****************************************************/
    private static boolean checkDirectory(String directory, Context ctx)
    {
    	File dir_geoloc = new File(directory);
        if(dir_geoloc.exists()==false || dir_geoloc.isDirectory()==false)
        {
        	return false;
        }
        return true;
    }
    /************************************************/
    /* Check if a file exists or not on the SD card */
    /************************************************/
    public static boolean checkFile(String filename, Context ctx)
    {
    	File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + filename);
        if(file.exists()==false || file.isFile()==false)
        {
        	FileUtilities.saveLog("Missing file", filename, 2);
        	return false;
        }
        return true;
    }
    /*********************************/
    /* Check if a SD card is present */
    /*********************************/
    public static boolean isSdPresent()
    {
    	return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
	}	


	public static Context getAppContext() {
		return context;
	}
	public void onterminate() {
		GPSTools.free();
		super.onTerminate();
	}


	// Moved in main activity
//	public void updateSensorData(ArrayList<SensorData> datas,
//			double lastDeltaTime, SensorData lastValues) {
//		// TODO Auto-generated method stub
//		
//	}
}